package com.woniuxy.huayoung.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.huayoung.annotations.RequirePermission;
import com.woniuxy.huayoung.entity.Perm;
import com.woniuxy.huayoung.entity.Role;
import com.woniuxy.huayoung.entity.User;
import com.woniuxy.huayoung.enums.ResponseEnum;
import com.woniuxy.huayoung.enums.TokenEnum;
import com.woniuxy.huayoung.result.ResponseResult;
import com.woniuxy.huayoung.service.RoleService;
import com.woniuxy.huayoung.service.UserService;
import com.woniuxy.huayoung.utils.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

@Component   //加入IOC容器
public class PermsInterceptor extends HandlerInterceptorAdapter {
    @Resource
    private UserService userService;
    @Resource
    private RoleService roleService;

    //日志
    private static final Logger logger = LoggerFactory.getLogger(PermsInterceptor.class);

    //在handler方法执行之前执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        ResponseResult<String> responseResult = new ResponseResult<>();
        //设置响应头
        response.setContentType("application/json;charset=utf-8");

        logger.debug("拦截请求");
        //得到token
        String token = request.getHeader("authorization");

        //1.得到即将被访问的方法
        //如果是请求的handler中的方法
        if (handler instanceof HandlerMethod){
            logger.debug("获取被请求的方法");
            HandlerMethod handlerMethod = (HandlerMethod)handler;
            //
            Method method = handlerMethod.getMethod();
            logger.debug("判断方法上是否有指定的注解");
            if (method.isAnnotationPresent(RequirePermission.class)){
                //判断token是否为null
                if (token == null){
                    logger.debug("没有登录");
                    responseResult.setCode(500);
                    responseResult.setMessage("你还没有登录");
                    responseResult.setStatus(ResponseEnum.NO_LOGIN);
                    String json = new ObjectMapper().writeValueAsString(responseResult);
                    //返回数据
                    response.getWriter().write(json);

                    return false;
                }
                //校验token：有可能伪造、过期
                if (JwtUtil.verify(token) == TokenEnum.TOKEN_FAIL){
                    logger.debug("token非法");

                    responseResult.setCode(500);
                    responseResult.setMessage("小样");
                    String json = new ObjectMapper().writeValueAsString(responseResult);
                    //返回数据
                    response.getWriter().write(json);

                    return false;
                }
                //判断是否过期
                if (JwtUtil.verify(token) == TokenEnum.TOKEN_EXPIRE){
                    logger.debug("token过期，重新生成token");
                    //重新生成token
                    token = JwtUtil.generateToken(JwtUtil.getAccount(token));
                    //更新前台的token
                    //将token放到响应头
                    logger.debug("将token设置到响应头，返回给前端");
                    response.setHeader("authorization",token);
                    //将该响应头暴露给第三方
                    response.setHeader("Access-Control-Expose-Headers","authorization");
                }


                logger.debug("方法上有注解,得到注解对象");
                RequirePermission rp = method.getDeclaredAnnotation(RequirePermission.class);
                logger.debug("获取注解中的值");
                String perms = rp.value();
                logger.debug("value = " + perms);

                //通过当前用户的账号，查询出他的所有权限进行对比
                String telephone = JwtUtil.getAccount(token);
                //调用service查询数据库数据
                User user = userService.findByTelephone(telephone);
                //查询角色信息绑定到result
                Integer uid = user.getId();//用户id
                Role role = roleService.findByUid(uid);
                logger.debug(role.toString());
                user.setRole(role);
                //遍历当前用户的权限

                for(Perm p : role.getPerms()){
                    if (p.getName().equals(perms)) {
                        logger.debug("有权限,放行");
                        return true;
                    }
                }

                //
                logger.debug("没有权限操作,拒绝请求");
                responseResult.setCode(500);
                responseResult.setMessage("你没有权限");
                responseResult.setStatus(ResponseEnum.NO_PERMISSION);

                //
                String json = new ObjectMapper().writeValueAsString(responseResult);
                //返回数据
                response.getWriter().write(json);
                return false;
            }
        }


        return super.preHandle(request, response, handler);
    }
}
